# coding: utf-8
import os, sys, string
import gettext
import urllib2, traceback
import cStringIO
import copy, types, re
import mypprint, json
import wx
import wx.aui
import wx.html as html
import wx.grid
from wx.lib import dialogs
from wx.lib.mixins.listctrl import CheckListCtrlMixin
import wx.lib.scrolledpanel as scrolled
import wx.lib.sized_controls as sc
import wx.lib.rcsizer as rcs

home  = os.path.dirname(os.path.abspath(__file__))

# 菜单配置
# menu_name, [[id, id_name, str, event_function],]
menus    = [u'文件', [[wx.NewId(), 'ID_FILE_EXIT', u'退出', 'OnFileExit'],]]

# 工具栏配置
# [[id, id_name, str, image_path, event_function],]
toolbars = [[wx.NewId(), 'ID_TB_ORDER', u'订单列表', os.path.join(home, 'images', 'order.png'), 'OnOrder'],
            [wx.NewId(), 'ID_TB_SHOW', u'显示所有窗口', os.path.join(home, 'images', 'win.png'), 'OnShowWin'],
            [wx.NewId(), 'ID_TB_PRINT', u'打印', os.path.join(home, 'images', 'print.png'), 'OnPrint'],
            [wx.NewId(), 'ID_TB_EXIT', u'退出', os.path.join(home, 'images', 'exit.png'), 'OnFileExit']
            ]


class OrderData:
    '''订单数据'''
    def __init__(self):
        self.data  = []
        self.index = {}

        self.order_map = {
            'order_id': u'订单ID',
            'shop_id': u'店铺ID',
            'tid': u'淘宝交易号',
            'alipay_no': u'支付宝交易号',
            'created': u'交易创建时间',
            'modified': u'交易修改时间',
            'pay_time': u'付款时间',
            'consign_time': '卖家发货时间',
            'end_time': u'交易结束时间',
            'insert_time': u'订单入库时间',
            'update_time': u'订单修改时间',
            'adjust_fee': u'卖家手工调整金额',
            'available_confirm_fee': u'交易中剩余确认收货金额',
            'total_fee': u'商品金额',
            'post_fee': u'邮费',
            'commission_fee': u'交易佣金',
            'cod_fee': u'货到付款服务费',
            'discount_fee': u'系统优惠金额',
            'price': u'商品价格',
            'payment': u'实付金额',
            'received_payment': u'卖家实际收到的支付宝金额',
            'buyer_obtain_point_fee': u'买家反点接分',
            'point_fee': u'买家使用积分',
            'real_point_fee': u'买家实际使用积分',
            'type': u'交易类型',
            'shipping_type': u'创建交易时物流方式',
            'status': u'交易状态',
            'order_status': u'自定义订单状态',
            'seller_rate': u'卖家是否已评',
            'buyer_rate': u'买家是否已评',
            'buyer_memo': u'买家备注',
            'seller_memo': u'卖家备注',
            'trade_memo': u'交易备注',
            'num': u'商品购买数量',
            'num_iid': u'商品数字编号',
            'pic_path': u'商品图片',
            'buyer_nick': u'买家昵称',
            'buyer_alipay_no': u'买家支付宝帐号',
            'buyer_email': u'买家邮件地址',
            'receiver_name': u'收货人姓名',
            'receiver_mobile': u'收货人手机',
            'receiver_phone': u'收货人电话',
            'receiver_state': u'省份',
            'receiver_city': u'城市',
            'receiver_district': u'地区',
            'receiver_address': u'详细地址',
            'receiver_zip': u'邮编',
            'trade_from': u'交易来源'
            }

        self.order_item_map = {
            'item_id': u'ID',
            'order_id': u'父订单ID',
            'tid': u'父订单编号',
            'oid': u'子订单编号',
            'num_iid': u'商品ID',
            'outer_iid': u'商家外部编码',
            'outer_sku_id': u'外部SKU的ID',
            'cid': u'商品类ID',
            'title': u'商品标题',
            'pic_path': u'商品图片',
            'num': u'购买数量',
            'price': u'商品价格',
            'sku_id': u'商品最小库存单位ID',
            'sku_properties_name': u'SKU的值',
            'item_meal_name': u'套餐值',
            'total_fee': u'应付金额',
            'discount_fee': u'订单优惠金额',
            'adjust_fee': u'手工调整金额',
            'payment': u'买家实付金额',
            'status': u'订单状态',
            'refund_status': u'退款状态',
            'buyer_rate': u'买家是否已评',
            'seller_rate': u'卖家是否已评'
        }

        self.user_map = {
            'user_id': u'会员ID',
            'shop_id': u'店铺ID',
            'tb_uid': u'淘宝用户ID',
            'nick': u'用户昵称',
            'sex': u'性别',
            'buyer_credit': u'买家信用',
            'seller_credit': u'卖家信用',
            'location': u'居住地',
            'created': u'用户注册时间',
            'last_visit': u'最近登录时间',
            'birthday': u'生日',
            'promoted_type': u'是否实名认证',
            'alipay_bind': u'是否绑定',
            'alipay_account': u'支付宝账户',
            'alipay_no': u'支付宝ID',
            'avatar': u'卖家头像',
            'email': u'买家邮件地址',
            'magazine_subscribe': u'是否订阅淘宝天下',
        }
        self.order_status_map = {
            'trade_no_create_pay':u'没有创建支付宝交易',
            'wait_buyer_pay':u'等待买家付款',
            'wait_seller_send_goods':u'等待卖家发货',
            'wait_buyer_confirm_goods':u'等待买家确认收货',
            'trade_buyer_signed':u'买家已签收',
            'trade_finished':u'交易成功',
            'trade_closed':u'交易关闭',
            'trade_closed_by_taobao':u'交易被淘宝关闭',
        }

        self.order_type_map = {
            'fixed': u'一口价',
            'auction': u'拍卖',
            'guarantee_trade': u'一口价、拍卖',
            'auto_deliverry': u'自动发货',
            'independent_simple_trade': u'旺店入门版交易',
            'independent_shop_trade': u'旺店标准版交易',
            'ec': u'直冲',
            'cod': u'货到付款',
            'fenxiao': u'分销',
            'game_equipment': u'游戏装备',
            'shopex_trade': u'ShopEX交易',
            'netcn_trade': u'万网交易',
            'external_trade': u'统一外部交易'
        }

        self.order_shipping_type_map = {
            'free': u'卖家承担运费',
            'post': u'平邮',
            'express': u'快递',
            'ems': u'EMS',
            'virtual': u'虚拟物品'
        }

        self.order_trade_from_map = {
            'wap': u'手机',
            'hital': u'嗨淘',
            'top': u'TOP平台',
            'taobao': u'普通淘宝'
        }

        self.order_item_refund_status_map = {
            'wait_seller_agree': u'买家已经申请退款，等待卖家同意',
            'wait_buyer_return_goods': u'卖家已经同意退款，等待买家退货',
            'wait_seller_confirm_goods': u'买家已经退货，等待卖家确认收货',
            'seller_refuse_buyer': u'卖家拒绝退款',
            'closed': u'退款关闭',
            'success': u'退款成功',
            'no_refund': u'没有退款'
        }
    
        self.orderurl = 'http://office.commence.cn/index.php?s=/pyapi/OrderItemList/'
        self.orderurl_param = {'status':'', 
                               'buyer_nick':'', 
                               'start_created':'',
                               'end_created':''}

        self.itemurl = 'http://office.commence.cn/index.php?m=pyapi&a=OrderDetail&tid=%d'

        self.data = []
        
        self.orderurl2 = 'http://office.commence.cn/index.php?m=pyapi&a=OrderDetail&tid=%d&GetFather=1'

    def _getdata(self, url):
        try:
            if url.find('tid') == -1:
                fpath = 'data.json'
            else:
                #fpath = 'item.json'
                fpath = None

            if fpath and os.path.isfile(fpath):
                f = open(fpath, 'r')
                s = f.read()
                f.close()
                x = json.loads(s)
                return x['data']

            s = urllib2.urlopen(url).read()
            x = json.loads(s)
            self.data = x['data']
            return x['data']
        except Exception, e:
            print 'open url error:', url
            traceback.print_exc()
            return None

    def _create_order_url(self, status, starttm, endtm):
        param = '' 
        if status:
            param += '&status=' + status
        if starttm:
            param += '&start_created=' + starttm
        if endtm:
            param += '&end_created=' + endtm

        return self.orderurl + param

    def _format_order(self, data):
        for row in data:
            row['status']     = row['status'].lower()
            row['status_str'] = self.order_status_map[row['status']]
            row['type_str']   = self.order_type_map[row['type']]
            row['shipping_type_str'] = self.order_shipping_type_map[row['shipping_type']]

            if not row.has_key('num'):
                row['num'] = 0
                row['pic_path'] = ''
                row['price'] = 0

            if not row.has_key('consign_time'):
                row['consign_time'] = ''

            if not row.has_key('pay_time'):
                row['pay_time'] = ''

            row['buyer_alipay_no'] = ''
            row['alipay_no'] = ''
            row['buyer_email'] = ''
            row['invoice_name'] = ''

            if not row.has_key('end_time'):
                row['end_time'] = '0000-00-00 00:00:00'

            if not row.has_key('receiver_phone'):
                row['receiver_phone'] = ''

            if not row.has_key('buyer_memo'):
                row['buyer_memo'] = ''

            if not row.has_key('buyer_message'):
                row['buyer_message'] = ''

        return data

    def getOrder(self, status='', starttm='', endtm=''):
        url = self._create_order_url(status, starttm, endtm)
        print 'url:', url
        obj = self._getdata(url)
        return self._format_order(obj)

    def _create_item_url(self, oid):
        return self.itemurl % (int(oid))

    def _format_item(self, data):
        if type(data) == types.DictType:
            data = [data]  
        for row in data:
            row['status']     = row['status'].lower()
            row['status_str'] = self.order_status_map[row['status']]
 
        return data

    def getOrderItem(self, oid):
        url = self._create_item_url(oid)
        print 'item url:', url
        obj = self._getdata(url)
        mypprint.pprint(obj)
        return self._format_item(obj)

    def getOrderFather(self, oid):
        url = self._create_item_url(oid)
        print 'item url:', url
        obj = self._getdata(url)
        return self._format_order(obj)

    def getUser(self, uid):
        pass



class LeftTree (wx.TreeCtrl):
    '''左边树状结构'''
    def __init__(self, parent):
        self.parent = parent
        super(LeftTree, self).__init__(parent, -1, wx.Point(0,0), wx.Size(200,200),
                    style=wx.TR_DEFAULT_STYLE)
        # 图标
        imagesize = (16, 16)
        self.imagelist = wx.ImageList(imagesize[0], imagesize[1])
        self.rootidx   = self.imagelist.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, imagesize))
        # 设置图标列表
        self.SetImageList(self.imagelist)
        
        self.init()
    
    def init(self):
        # 添加树的结构
        self.root = self.AddRoot(u'商城管理')
        self.SetItemImage(self.root, self.rootidx, wx.TreeItemIcon_Normal)
        item = self.AppendItem(self.root, u'订单管理')
        self.SetItemImage(item, self.rootidx, wx.TreeItemIcon_Normal)
        self.Expand(self.root)



class OrderBook (wx.Notebook):
    '''订单列表Tab'''
    def __init__(self, parent):
        self.parent = parent
        wx.Notebook.__init__(self,parent, -1, size=(21, 21), style=wx.BK_DEFAULT)
        
        self.pages = {}
 
    def addPages(self, pages):
        '''添加一个Tab页'''
        self.pages = {}

        for name,page in pages:
            self.AddPage(page, name)
            self.pages[name] = page

    def reload(self):
        '''加载数据'''
        if not self.pages:
            return
        try:
            data = self.parent.data.getOrder()
        except Exception, e:
            dialogs.alertDialog(self, str(e), u'数据加载失败!')
            return 
        
        for page in self.pages.values():
            page.DeleteAllItems()
        self.setData(data)

    def setData(self, items):
        '''设置数据项'''
        self.data = items
        for i in range(0, len(items)):
            #print '==== item %d,%d ====' % (i, len(items))
            item = items[i]
            item['_id'] = i
            page = self.pages[u'所有'].addData(item)

            if item['status'] == 'wait_seller_send_goods':
                self.pages[u'待发货'].addData(item)
            elif item['status'] == 'wait_buyer_confirm_goods':
                self.pages[u'已发货'].addData(item)
                self.pages[u'未付款'].addData(item)

            if item['status'] == 'trade_finished' and item['seller_rate'] != 'true':
                self.pages[u'需评价'].addData(item)


    def rateConv(self, seller_rate, buyer_rate):
        if seller_rate == 'true' and buyer_rate == 'true':
            return u'双方已评'
        if seller_rate == 'true':
            return u'卖家已评'
        if buyer_rate == 'true':
            return u'买家已评'

        return u'双方都没评'


    def select(self, i):
        item = self.data[i]
        self.parent.descbook.select(item)

class OrderList (wx.ListCtrl, CheckListCtrlMixin):
    '''订单主列表'''
    def __init__(self, parent):
        self.parent = parent
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
        CheckListCtrlMixin.__init__(self)
 
        self.colnames = [u'宝贝', u'买家', 
                         u'付款时间', u'发货时间', u'数量', 
                         u'商品总价', u'邮费', 
                         u'交易类型', u'发货方式', 
                        ]

        self.colkeys = ['', 
                        'buyer_nick', 
                        'pay_time', 
                        'consign_time', 
                        'num', 
                        'payment', 
                        'post_fee', 
                        'type_str', 
                        'shipping_type_str', 
                        ]
        self.data = []
        self.init()

    def init(self):
        # 创建列
        for i in range(0, len(self.colnames)):
            self.InsertColumn(i, self.colnames[i])
        # 设置列宽度
        self.SetColumnWidth(0, 200)
        self.SetColumnWidth(1, 150)
        self.SetColumnWidth(2, 130)
        self.SetColumnWidth(3, 130)

        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self)

    def OnItemSelected(self, event):
        '''某项被选择'''
        self.currentItem = event.m_itemIndex
        print 'select:', self.currentItem
        
        self.parent.select(self.currentItem)

    def OnCheckItem(self, index, flag):
        data = self.GetItemData(index)
        if flag:
            print 'checked'
        else:
            print 'unchecked'

    def addData(self, item):
        self.data.append(item)

        idx = None
        for i in range(0, len(self.colkeys)):
            k = self.colkeys[i]
            if k and type(k) == types.StringType:
                v = item[k]
                
                if type(v) == types.UnicodeType:
                    #v = v.encode('utf-8')
                    pass
                else:
                    v = str(v)
            else:
                v = str(k)
            #print 'v:', v, type(v), i
            if idx is None:
                idx = self.InsertStringItem(sys.maxint, v)
            else:
                self.SetStringItem(idx, i, v)
        self.SetItemData(idx, item['_id'])

    def getAllSelected(self):
        result = []
        idx = -1
        while True:
            idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_DONTCARE)
            if idx == -1:
                break
            if self.IsChecked(idx):
                result.append(self.GetItemData(idx)) 
        return result


    def getOrderItemFather(self):
        data = self.parent.data.getOrderFather(item['tid'])
        mypprint.pprint(data)


class OrderItemList (wx.ListCtrl, CheckListCtrlMixin):
    '''子订单列表'''
    def __init__(self, parent):
        self.parent = parent
        wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
        CheckListCtrlMixin.__init__(self)
 
        self.colnames = [u'宝贝', u'单价(元)', u'数量', 
                         u'优惠', u'交易状态']
        self.colkeys  = ['title', 'price', 'num', 'discount_fee', 'status_str']
        self.data     = []

        self.init()

    def init(self):
        for i in range(0, len(self.colnames)):
            self.InsertColumn(i, self.colnames[i])
        self.SetColumnWidth(0, 400)


    def setData(self, item):
        print 'sub items:', item
        frame = self.parent.parent.parent
        self.DeleteAllItems()
        subitems = item.get('_subitems', None)
        if subitems is None:
            subitems = frame.data.getOrderItem(item['tid'])
            if subitems:
                item['_subitems'] = subitems
                for row in subitems:
                    row['_id'] = item['_id']
                

            
        self.data = subitems
        for item in subitems:
            self.addData(item)

    def addData(self, item):
        idx = None
        for i in range(0, len(self.colkeys)):
            k = self.colkeys[i]
            if k and type(k) == types.StringType:
                v = item[k]
                if type(v) == types.UnicodeType:
                    #v = v.encode('utf-8')
                    pass
                else:
                    v = str(v)
            else:
                v = str(k)
            #print 'v:', v, type(v), i
            if idx is None:
                idx = self.InsertStringItem(sys.maxint, v)
            else:
                self.SetStringItem(idx, i, v)
        self.SetItemData(idx, item['_id'])


class OrderDesc (scrolled.ScrolledPanel):
    '''订单详细信息'''
    def __init__(self, parent):
        scrolled.ScrolledPanel.__init__(self, parent, -1)
        self.parent = parent
        sizer = wx.BoxSizer(wx.VERTICAL)
        descsizer = wx.FlexGridSizer(3, 6, 5, 5)

        self.names = ((u'会员名', u'实收款', u'订单编号'),
                      (u'支付宝', u'商品总价', u'支付宝交易号'),
                      (u'邮件', u'运费', u'成交时间'))
    
        self.items = {} 
        
        manyitems = []
        for row in self.names:
            for name in row:
                fname = wx.StaticText(self, -1, name)
                ftext = wx.TextCtrl(self, -1, '')
                self.items[name] = ftext

                manyitems.append((fname, 0, wx.EXPAND))
                manyitems.append((ftext, 0, wx.EXPAND))
            
        descsizer.AddMany(manyitems)
        descsizer.AddGrowableCol(1)
        descsizer.AddGrowableCol(3)
        descsizer.AddGrowableCol(5)
       
        sizer.Add(descsizer, 0, wx.EXPAND)
        # add spacer
        sizer.Add((-1,5), 0, wx.EXPAND)
        self.itemlist = OrderItemList(self)
        sizer.Add(self.itemlist, 0, wx.EXPAND)

        self.SetSizer(sizer)

    def setData(self, item):
        self.items[u'会员名'].SetValue(item['buyer_nick'])
        self.items[u'实收款'].SetValue(item['payment'])
        self.items[u'订单编号'].SetValue(item['tid'])
        self.items[u'支付宝'].SetValue(item['buyer_alipay_no'])
        self.items[u'商品总价'].SetValue(item['total_fee'])
        self.items[u'支付宝交易号'].SetValue(item['alipay_no'])
        self.items[u'邮件'].SetValue(item['buyer_email'])
        self.items[u'运费'].SetValue(item['post_fee'])
        self.items[u'成交时间'].SetValue(item['end_time'])
   
        self.itemlist.setData(item)

class OrderLogis (scrolled.ScrolledPanel):
    '''物流信息'''
    def __init__(self, parent):
        scrolled.ScrolledPanel.__init__(self, parent, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)

        infosizer = self.addFirstRow()
        sizer.Add(infosizer, 0, wx.EXPAND)
        
        recvsizer = self.addRecvInfo()
        sizer.Add(recvsizer, 0, wx.EXPAND|wx.ALL, 5)

        sizer.Add((-1, 5), 0, wx.EXPAND)

        fpsizer = wx.BoxSizer(wx.HORIZONTAL)
        fpsizer.Add(wx.StaticText(self, -1, u'发票抬头', size=(60,60)), 0, wx.EXPAND|wx.LEFT, 5)
        self.fp = wx.TextCtrl(self, -1, u'', style=wx.TE_MULTILINE)
        fpsizer.Add(self.fp, 1, wx.EXPAND|wx.RIGHT, 10)
         
        sizer.Add(fpsizer, 0, wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)

    def addFirstRow(self):
        infosizer = wx.FlexGridSizer(1, 5, 5, 5)

        infoitems = []
        infoitems.append((wx.StaticText(self, -1, u'快递公司'), 0, wx.ALL|wx.EXPAND, 4))
        self.kuaidi = wx.TextCtrl(self, -1, u'')
        infoitems.append((self.kuaidi, 0, wx.EXPAND|wx.ALL, 2))

        infoitems.append((wx.StaticText(self, -1, u'运单号'), 0, wx.EXPAND|wx.ALL, 4))
        self.yundan = wx.TextCtrl(self, -1, u'')
        infoitems.append((self.yundan, 0, wx.EXPAND|wx.ALL, 2))

        self.xiazai = wx.Button(self, -1, u'重新下载此订单')
        infoitems.append((self.xiazai, 0, wx.EXPAND))

        infosizer.AddMany(infoitems)
        infosizer.AddGrowableCol(1)
        infosizer.AddGrowableCol(3)

        return infosizer


    def addRecvInfo(self):
        recvtitle = wx.StaticBox(self, -1, u'收件人信息') 
        recvbox   = wx.StaticBoxSizer(recvtitle, wx.VERTICAL)
       
        recvsizer = wx.GridBagSizer(4, 6)

        recvsizer.Add(wx.StaticText(self, -1, u'姓名'), (0, 0), border=3, flag=wx.NORTH)
        self.xm = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.xm, (0, 1), flag=wx.ALL, border=1)
 
        recvsizer.Add(wx.StaticText(self, -1, u'所在地区'), (0, 2), flag=wx.NORTH, border=3)
        self.dq1 = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.dq1, (0, 3), flag=wx.ALL, border=1)
        self.dq2 = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.dq2, (0, 4), flag=wx.ALL, border=1)
        self.dq3 = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.dq3, (0, 5), flag=wx.ALL, border=1)

        recvsizer.Add(wx.StaticText(self, -1, u'邮编'), (1, 0), flag=wx.NORTH, border=3)
        self.yb = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.yb, (1, 1), flag=wx.ALL, border=1)
 
        recvsizer.Add(wx.StaticText(self, -1, u'街道地址'), (1, 2), flag=wx.NORTH, border=3)
        self.jd = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.jd, (1, 3), (1, 3), flag=wx.EXPAND|wx.ALL, border=1)
 
        recvsizer.Add(wx.StaticText(self, -1, u'手机'), (2, 0), flag=wx.NORTH, border=3)
        self.sj = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.sj, (2, 1), flag=wx.ALL, border=1)
 
        recvsizer.Add(wx.StaticText(self, -1, u'单位'), (2, 2), flag=wx.NORTH, border=3)
        self.dw = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.dw, (2, 3), (1, 3), flag=wx.ALL, border=1)
               
        recvsizer.Add(wx.StaticText(self, -1, u'电话'), (3, 0), flag=wx.NORTH, border=3)
        self.dh = wx.TextCtrl(self, -1, u'')
        recvsizer.Add(self.dh, (3, 1), flag=wx.ALL, border=1)
    
        recvbox.Add(recvsizer, 0, wx.EXPAND|wx.TOP, 5)

        return recvbox

    def setData(self, item):
        self.xm.SetValue(item['receiver_name'])
        self.dq1.SetValue(item['receiver_state'])
        self.dq2.SetValue(item['receiver_city'])
        self.dq3.SetValue(item['receiver_address'])

        self.yb.SetValue(item['receiver_zip'])
        self.jd.SetValue(item['receiver_address'])
        self.sj.SetValue(item['receiver_mobile'])
        self.dh.SetValue(item['receiver_phone'])
        self.fp.SetValue(item['invoice_name'])


class OrderRemark (scrolled.ScrolledPanel):
    '''备注留言'''
    def __init__(self, parent):
        scrolled.ScrolledPanel.__init__(self, parent, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(wx.StaticText(self, -1, u'备注'), 0, wx.EXPAND|wx.NORTH|wx.SOUTH, 5)
        self.beizhu = wx.TextCtrl(self, -1, u'', style=wx.TE_MULTILINE)
        sizer.Add(self.beizhu, 0, wx.EXPAND)
        sizer.Add(wx.StaticText(self, -1, u'买家留言'), 0, wx.EXPAND|wx.NORTH|wx.SOUTH, 5)
        self.liuyan = wx.TextCtrl(self, -1, u'', style=wx.TE_MULTILINE)
        sizer.Add(self.liuyan, 0, wx.EXPAND)
        
        self.SetSizer(sizer)

    def setData(self, item):
        self.beizhu.SetValue(item['buyer_memo'])
        self.liuyan.SetValue(item['buyer_message'])

class OrderDescBook (wx.Notebook):
    '''订单详情部分Tab'''
    def __init__(self, parent):
        wx.Notebook.__init__(self,parent, -1, size=(21, 21), style=wx.BK_DEFAULT)
        self.parent = parent
    
        self.pages = ((u'订单详细信息', OrderDesc(self)), 
                      (u'物流信息', OrderLogis(self)), 
                      (u'备注留言', OrderRemark(self)))

        for name,page in self.pages:
            self.AddPage(page, name)

    def select(self, item):
        for name,page in self.pages:
            page.setData(item)
  
class TemplateData:
    '''快递模版'''
    def __init__(self):
        self.data = []


        self.zone = {u'发件人信息': 
                            {u'姓名':[], u'单位':[], u'地址':[], u'手机':[], u'电话':[], 
                             u'邮编':[], u'始发地':[], u'日期':[]},
                     u'收件人信息':
                            {u'姓名':[], u'单位':[], u'地址':[], u'手机':[], u'电话':[],
                             u'邮编':[], u'目的地':[], u'日期':[]},
                     'pic':'',
                     }
    
        # not used
        self.zone8 = {'发件人信息': 
                            {'姓名':[], '单位':[], '地址':[], '手机':[], '电话':[], 
                             '邮编':[], '始发地':[], '日期':[]},
                     '收件人信息':
                            {'姓名':[], '单位':[], '地址':[], '手机':[], '电话':[],
                             '邮编':[], '目的地':[], '日期':[]},
                     'pic':'',
                     'name':''
                     }

        self.filename = 'template/express.cf'

        
    def load(self):
        if not os.path.isfile(self.filename):
            self.create()
            return

        f = open(self.filename, 'r')
        lines = f.readlines()
        f.close()

        if not lines:
            self.create()
            return

        cwd = os.getcwd()
        print 'lines:', len(lines)
        data = []
        one  = None
        for line in lines:
            line = line.strip()
            if not line:
                continue

            if line.startswith('['):
                name = unicode(line[1:-1], 'gbk')
                one = {'name': name}
                data.append(one)
            else:
                parts = re.split(':|=|,', line)
                
                cate = unicode(parts[0], 'gbk')
                name = unicode(parts[1], 'gbk')

                if parts[0] in ['pic', 'name']:
                    one[cate] = os.path.join(cwd, name)
                    continue

                if not one.has_key(cate):
                    one[cate] = {}

                if len(parts) != 6:
                    pos = []
                else:
                    pos = map(int, [parts[2], parts[3], parts[4], parts[5]])

                one[cate][name] = pos
        self.data = data

        print 'open:'
        mypprint.pprint(data)


    def save(self):
        f = open(self.filename, 'w')
        for row in self.data:
            #print 'row:', row
            f.write('[%s]\n' % row['name'].encode('gbk'))
            f.write('pic=%s\n' % row['pic'].encode('gbk'))
            for k in row:
                if k in ['pic', 'name']:
                    continue
                for ki in row[k]:
                    pos = ','.join([str(x) for x in row[k][ki]])
                    f.write('%s:%s=%s\n' % (k.encode('gbk'), ki.encode('gbk'), pos))
        f.close()

    def create(self):
        result = []
        files = os.listdir('template')
        for fname in files:
            fname_u = unicode(fname, 'gbk')
            ext_u   = os.path.splitext(fname_u)
            ext     = os.path.splitext(fname)
            if len(ext) == 2 and ext[1] == '.jpg':
                obj = copy.deepcopy(self.zone)
                obj['pic'] = 'template/' + fname_u
                obj['name'] = ext_u[0]
                #result[ext_u[0]] = obj
                result.append(obj)

        #print 'create:', mypprint.pprint(result)
        self.data = result
        self.save()

    

    def allExpress(self):
        return [ x['name'] for x in self.data]

    def info(self, name):
        for x in self.data:
            if x['name'] == name:
                return x
        return None


class TemplateImage (wx.Panel):
    def __init__(self, parent):
        self.parent = parent
        wx.Panel.__init__(self, parent, -1, size=(1024,730)) 
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        
        self.data = None

    def setData(self, data):
        self.data = data
        self.Refresh()

    def OnPaint(self, evt):
        self.displayData(self.data)

    def displayData(self, data):
        dc = wx.PaintDC(self)
        dc.SetBackground(wx.Brush("WHITE"))
        dc.Clear()
        
        print 'ppi:', dc.GetPPI()

        if not data:
            return

        dc.SetFont(wx.Font(19, wx.SWISS, wx.NORMAL, wx.BOLD, True)) 
        picfile = self.data['pic'].encode('gbk')
        print 'picfile:', picfile, os.path.isfile(picfile), type(picfile), os.getcwd()
        bmp = wx.BitmapFromImage(wx.ImageFromStream(open(picfile,'rb')))

        dc.DrawBitmap(bmp, 0, 0, True)
        dc.SetFont(self.GetFont())
        dc.SetPen(wx.Pen(wx.Colour(255, 0, 0, wx.ALPHA_OPAQUE)))
        dc.SetBrush(wx.Brush(wx.Colour(255, 0, 0, 128)))
        dc.SetTextForeground(wx.Colour(255, 0, 0, 128))
    
        #mypprint.pprint(self.data)
        for k in data:
            if k in ['pic', 'name']:
                continue
            v = data[k]
            #print 'v:'
            #mypprint.pprint(v)
            for name, pos in v.iteritems():
                if pos:
                    #dc.DrawRectangle(pos[0], pos[1], pos[2], pos[3])
                    dc.DrawLine(pos[0], pos[1], pos[0]+pos[2], pos[1])
                    dc.DrawLine(pos[0], pos[1], pos[0], pos[1]+pos[3])

                    dc.DrawLine(pos[0]+pos[2], pos[1]+pos[3], pos[0]+pos[2], pos[1])
                    dc.DrawLine(pos[0]+pos[2], pos[1]+pos[3], pos[0], pos[1]+pos[3])

                    dc.DrawText(name, pos[0]+2, pos[1]+2)


class MyPrintout (wx.Printout):
    '''打印'''
    def __init__(self, data):
        wx.Printout.__init__(self)
        self.data = data

    def OnPrintPage(self, page):
        dc = self.GetDC()
        #print 'ppi:', dc.GetPPI()
        ppi_w, ppi_h = dc.GetPPI()

        wr = ppi_w / 96
        hr = ppi_h / 96

        for row in self.data:
            name = row[0]
            pos  = row[1]
            dc.DrawText(name, pos[0]*wr + 2, pos[1]*hr + 2)


class TemplateFrame (wx.Frame):
    def __init__(self, parent, pdata):
        self.parent = parent
        wx.Frame.__init__(self, parent, -1, title=u'选择快递模板', size=(1124,800))

        self.tdata = TemplateData()
        self.tdata.load()
        self.listdata = self.tdata.allExpress()
        self.pdata = pdata

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        # 左边快递列表 
        self.box = wx.ListBox(self, -1, (120, 50), (90, 120), self.listdata, wx.LB_SINGLE)
        sizer.Add(self.box, 0, wx.EXPAND) 
        
        vsizer = wx.BoxSizer(wx.VERTICAL)
        vpanel = wx.Panel(self, -1)
        # 右边显示快递单图片
        self.image = TemplateImage(vpanel)
        vsizer.Add(self.image, 0, wx.EXPAND|wx.ALL)

        dpanel = wx.Panel(vpanel, -1)
        # 显示打印和打印预览按钮
        dsizer = wx.FlexGridSizer(1, 2, 10, 10)
        p = []
        self.preview = wx.Button(dpanel, 10, u'打印预览', (20, 20))
        p.append((self.preview, 0, wx.EXPAND, 5)) 
        self.printer = wx.Button(dpanel, 10, u'打印', (20, 20))
        p.append((self.printer, 0, wx.EXPAND, 5)) 
        
        dsizer.AddMany(p)
        dpanel.SetSizer(dsizer)

        vsizer.Add(dpanel, 0, wx.EXPAND)
        vpanel.SetSizer(vsizer)

        sizer.Add(vpanel, 0, wx.EXPAND|wx.ALL)

        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnDClick, self.box)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
       
        self.Bind(wx.EVT_BUTTON, self.OnPreview, self.preview)
        self.Bind(wx.EVT_BUTTON, self.OnPrint, self.printer)

        self.printData = wx.PrintData()
        self.printData.SetPaperId(wx.PAPER_A4)
        #self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)

    def createDataForPrint(self, data, tdata, tname):
        sender_keys = tdata.zone[u'发件人信息'].keys()
        recver_keys = tdata.zone[u'收件人信息'].keys()
 
        keymap = {}
        for k in recver_keys:
            keymap[k] = ''

        keymap[u'姓名'] = 'receiver_name'
        keymap[u'单位'] = ''
        keymap[u'地址'] = 'receiver_address'
        keymap[u'手机'] = 'receiver_mobile'
        keymap[u'电话'] = 'receiver_phone'
        keymap[u'邮编'] = 'receiver_zip'
        keymap[u'目的地'] = 'receiver_city'
        keymap[u'日期'] = ''

        senderinfo = self.loadSenderInfo()
        tinfo = tdata.info(tname)
        
        mypprint.pprint(tinfo)

        pdata = []
        for row in data:
            one = []
            for k in recver_keys:
                km = keymap[k]
                if km:
                    #tsend = tinfo[u'发件人信息']
                    trecv = tinfo[u'收件人信息']
                    print 'key:', k, km
                    if row[km] and trecv[k]:
                        one.append((row[km], trecv[k]))
            for k in sender_keys:
                tsend = tinfo[u'发件人信息']
                print 'key:', k
                if tsend[k] and senderinfo[k]:
                    one.append((senderinfo[k], tsend[k]))

            pdata.append(one)

        print 'print data:', pdata
        return pdata

    def loadSenderInfo(self):
        global home
        senderfile = os.path.join(home, 'template', 'sender.cf')
        if not os.path.isfile(senderfile):
            return {}

        f = open(senderfile, 'r')
        lines = f.readlines()
        f.close()

        data = {}
        for line in lines:
            line = line.strip()
            if not line:
                continue
            parts = map(string.strip, line.split('='))
            name  = unicode(parts[0], 'gbk')
            value = unicode(parts[1], 'gbk')

            data[name] = value
        print 'sender:', mypprint.pprint(data)
        return data
    
    def OnClose(self, evt):
        self.Destroy()

    def OnDClick(self, evt):
        pos = self.box.GetSelection()

        self.image.setData(self.tdata.info(self.listdata[pos]))
    
    def OnPreview(self, event):
        pos   = self.box.GetSelection()
        tname = self.listdata[pos]
        pdata = self.createDataForPrint(self.pdata, self.tdata, tname)

        data         = wx.PrintDialogData(self.printData)
        printouts = []
        for p in pdata:
            printouts.append(MyPrintout(p))

        printout1 = MyPrintout(pdata[0])
        printout2 = MyPrintout(pdata[0])

        self.preview = wx.PrintPreview(printout1, printout2, data)

        if not self.preview.Ok():
            print("preview preblem ...\n")
            return

        pfrm = wx.PreviewFrame(self.preview, self.parent, u"打印预览")
        pfrm.Initialize()
        pfrm.SetPosition(self.GetPosition())
        pfrm.SetSize(self.GetSize())
        pfrm.Show(True)


    def OnPrint(self, evt):
        pos   = self.box.GetSelection()
        tname = self.listdata[pos]
        pdata = self.createDataForPrint(self.pdata, self.tdata, tname)

        pdd      = wx.PrintDialogData(self.printData)
        pdd.SetToPage(len(pdata))
        printer  = wx.Printer(pdd)
        
        for p in pdata:
            printout = MyPrintout(p)

        if not printer.Print(self.parent, printout, True):
            wx.MessageBox(u"打印出错了，可能是打印机设置问题。", u"打印中", wx.OK)
        else:
            self.printData = wx.PrintData( printer.GetPrintDialogData().GetPrintData() )
        printout.Destroy()



class TraderFrame (wx.Frame):
    '''主窗口'''
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self,  parent, id , title, 
                wx.DefaultPosition, wx.Size(1000,700),
                name='Trader', style=wx.DEFAULT_FRAME_STYLE)

        self.data = OrderData()

        self.makeMenu()
        self.makeToolbar()
        self.makeStatusBar()
        self.makeContent()

    def makeMenu(self):
        global menus
        self.menus = {}
        menubar = wx.MenuBar()
        for i in range(0, len(menus), 2):
            submenus = menus[i+1]
            m = wx.Menu()
            self.menus[menus[i]] = m
            for sub in submenus:
                setattr(self, sub[1], sub[0])
                m.Append(sub[0], sub[2])
                if sub[-1]:
                    self.Bind(wx.EVT_MENU, getattr(self, sub[-1]), id=sub[0])
            menubar.Append(m, menus[i])
                
        self.SetMenuBar(menubar) 

    def makeToolbar(self):
        global toolbars
        self.toolbar = wx.ToolBar(self, -1, wx.DefaultPosition, wx.Size(32,32), 
                                wx.TB_HORIZONTAL|wx.TB_FLAT|wx.TB_TEXT)
        self.toolbar.SetToolBitmapSize(wx.Size(32,32))

        for tb in toolbars:
            setattr(self, tb[1], tb[0])
            self.toolbar.AddLabelTool(tb[0], tb[2], 
                    wx.BitmapFromImage(wx.ImageFromStream(open(tb[3],'rb'))))
            if tb[-1]:
                self.Bind(wx.EVT_TOOL, getattr(self, tb[-1]), id=tb[0])
        self.toolbar.Realize()
        self.SetToolBar(self.toolbar)
        
    def makeStatusBar(self):
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetFieldsCount(1)
        self.SetStatusWidths([-1])

    def makeContent(self):
        self.mgr = wx.aui.AuiManager()
        self.mgr.SetManagedWindow(self)
        
        # add lefttree to aui
        self.lefttree =  LeftTree(self)
        self.mgr.AddPane(self.lefttree, wx.aui.AuiPaneInfo().Name('lefttree').
                        Left().Layer(1).Position(1).MaximizeButton(False))
    
        self.orderbook = OrderBook(self)
        self.pages = ((u'待发货', OrderList(self.orderbook)), 
                      (u'已发货', OrderList(self.orderbook)),
                      (u'未付款', OrderList(self.orderbook)), 
                      (u'退款中', OrderList(self.orderbook)), 
                      (u'需评价', OrderList(self.orderbook)), 
                      (u'所有',   OrderList(self.orderbook)), 
                      (u'手工下载',OrderList(self.orderbook)))
        self.orderbook.addPages(self.pages)
        self.mgr.AddPane(self.orderbook, wx.aui.AuiPaneInfo().Name('orderbook').
                        CaptionVisible(False).
                        CenterPane().Layer(0).Position(0).
                        CloseButton(False).MaximizeButton(False))

        self.descbook = OrderDescBook(self)
        self.mgr.AddPane(self.descbook, wx.aui.AuiPaneInfo().Name('descbook').
                        Caption(u'订单详情').
                        MinSize(wx.Size(-1,200)).Bottom().Layer(0).
                        Position(1).MaximizeButton(False))
        self.mgr.Update()

    def OnPrint(self, event):
        idx   = self.orderbook.GetSelection()
        page  = self.pages[idx][1]
        items = page.getAllSelected()
        print 'print items:', items

        if not items:
            return
        pdata = []
        for i in items:
            pdata.append(page.data[i])

        frame = TemplateFrame(self, pdata)
        frame.CenterOnScreen()
        frame.Show()


    def OnFileExit(self, event):
        self.Destroy()
        
    def OnOrder(self, event):
        self.orderbook.reload()
    
    def OnShowWin(self, event):
        self.mgr.GetPane('lefttree').Show()
        self.mgr.GetPane('orderbook').Show()
        self.mgr.GetPane('descbook').Show()
        self.mgr.Update()

class Trader (wx.App):
    def __init__(self):
        wx.App.__init__(self, 0)

    def OnInit(self):
        self.frame = TraderFrame(None, 101, u'淘宝商家助手')
        self.frame.CenterOnScreen()
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        self.Bind(wx.EVT_ACTIVATE_APP, self.OnActivate)
        return True 

    def OnActivate(self, event):
        event.Skip()

def main():
    app = Trader()
    app.MainLoop()

if __name__ == '__main__':
    main()


